.\" bootiso - create a bootable USB drive from an image file
.\" Copyright (C) 2018-2020 jules randolph <jules.sam.randolph@gmail.com>
.\"
.\" This program is free software: you can redistribute it and/or modify
.\" it under the terms of the GNU General Public License as published by
.\" the Free Software Foundation, either version 3 of the License, or
.\" (at your option) any later version
.\" This program is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
.\" GNU General Public License for more details
.\" You should have received a copy of the GNU General Public License
.\" along with this program.  If not, see <https://www.gnu.org/licenses/>.
.
.Dd May 22, 2020
.Dt BOOTISO 1
.Os bootiso 4.1.1
.Sh NAME 
.Nm bootiso 
.Nd create a bootable USB drive from an image file
.
.
.Sh SYNOPSIS 
.\" Install auto action
Each line depicts an action, with the exception of the first three lines
which describe
.Sy install
action modes. Respectively,
.Dq Automatic,
.Dq Image-Copy
and
.Dq Mount-Rsync
modes. In the latest two,
.Ar INSTALLMODS
refers to an option enumerated in the first
.Dq Automatic
synopsis line.
When both short and long options exist, only
one is printed.
.Pp
.Nm bootiso
.Op Fl aJMy
.Op Fl d Ar device
.Oo
.Cm --no-hash-check | 
.Op Cm --hash-file Ar hashfile
.Op Cm --force-hash-check
.Oc
.Op Cm --no-size-check
.Op Cm --no-usb-check
.Op Cm --
.Ar imagefile
.\" Install Image-Copy mode
.Nm bootiso
.Cm --icopy
.Op Ar "INSTALLMODS" No ...
.Op Cm --dd-bs Ar blocksize
.Oo
.Fl D
.Op Cm --data-part-fs Ar fstype
.Oc
.Op Cm --
.Ar imagefile
.\" Install Mount-Rsync mode
.Nm bootiso
.Cm --mrsync
.Op Ar "INSTALLMODS" No ...
.Op Fl L Ar label
.Op Fl F Ar fstype
.Op Cm --gpt
.Op Cm --no-wimsplit
.Op Cm --part-type Ar typeid
.Op Cm --local-bootloader | Cm --remote-bootloader Ar version
.Op Cm --
.Ar imagefile
.
.\" Format action
.Nm bootiso
.Fl f
.Op Fl ay
.Op Fl d Ar device
.Op Fl L Ar label
.Op Fl F Ar fstype
.Op Cm --gpt
.Op Cm --no-usb-check
.Op Cm --part-type Ar typeid
.
.\" Inspect action
.Nm bootiso
.Fl i
.Op Fl M
.Oo
.Cm --no-hash-check | 
.Op Cm --hash-file Ar hashfile
.Op Cm --force-hash-check
.Oc
.Op Cm --
.Ar imagefile
.
.\" List usb drives action
.Nm bootiso
.Fl l
.Op Cm --no-usb-check
.
.\" Probe action
.Nm bootiso
.Fl p
.Op Fl M
.Oo
.Cm --no-hash-check | 
.Op Cm --hash-file Ar hashfile
.Op Cm --force-hash-check
.Oc
.Op Cm --no-usb-check
.Op Cm --
.Ar imagefile
.
.\" Help action
.Nm bootiso
.Fl h
.
.\" Version action
.Nm bootiso
.Fl v
.
.
.Sh DESCRIPTION
.Nm
is a command-line utility aimed at simplifying the task of 
.Dq burning
a USB storage device with a bootable disk image.
The program can be safely called with no options. Read
.Sx EXAMPLES
section for a quick summary of typical invocations.
.Ss Features
One can use 
.Xr dd 1
utility for hybrid images, but not all images are
hybrid and the operation is error-prone, especially for amateur UNIX users, thus its
.Dq disk destroyer
nickname. In addition to offering a safety layer (see
.Sx GUARDRAILS
section),
.Nm
will handle hybrid and non-hybrid SYSLINUX or UEFI compliant images such
as any GNU-Linux, Windows or rescue live-cds like UltimateBootCD images.
This program also offers additional features, such as quickly format a USB
drive, inspecting an image file or listing USB-connected drives. Supported
images format are plain disk images (img) and ISO 9660 files.
.Pp
.Nm
can be invoked with two types of options: actions and
modifiers.
Actions determine the goal of the program execution, and
modifiers define the specifics to reach that goal.
At most one action flag can be set. In the absence
of action flag,
.Nm
assumes
.Sy install
action in
.Dq Automatic
mode: inspect
.Ar imagefile
boot capabilities and find the best way to make a bootable USB drive
(see
.Sx "INSTALL MODES"
bellow).
.
.Ss Actions
.Bl -tag
.It Fl f, Cm --format
Wipe and format the selected USB device.
.Sy Default Behavior:
If no device were
explicitly selected with
.Cm --device
modifier,
.Nm
will prompt for selection. With no further notice,
.Nm
will write a MBR partition table and format a FAT32 partition.
These defaults can be overridden with
.Cm --gpt
and
.Cm --fs
modifiers.
.It Fl h, Cm --help
Display a concise list of options then exits.
.It Fl i, Cm --inspect
Inspect
.Ar imagefile
boot capabilities and how
.Nm
can handle it. In addition, validate this file
against a hash file if one is found, then exit.
.It Fl l, Cm --list-usb-drives
List USB drives then exits.
Diverse information will be printed such as model,
vendor, size and device file name which can be later used with
.Fl d, Cm --device
modifier.
.It Fl p, Cm --probe
Probe
is equivalent to
.Sy inspect
followed by 
.Sy list USB drives
actions.
.It Fl v, Cm --version
Displays
.Nm
version then exits.
.El
.Ss Generic Modifiers
Use generic modifiers knowingly as some might override default safe behaviors.
.Bl -tag
.It Fl a, Cm --autoselect
Enable
.Dq autoselect
behavior in combination with 
.Cm --assume-yes
modifier.
It will automatically select a USB drive device if there is exactly one connected
to the system.
.Pp
.Sy Notice:
The
.Dq autoselect
behavior is the default behavior when
.Dq assume yes
is not enabled, unless either
.Cm --device
or
.Cm --no-usb-check
modifiers are set.
.It Fl d Ar device, Cm --device Ar device
Select
.Ar device
block file as the action target.
When
.Ar device
is not connected through a USB bus,
.Nm
will fail and exit, unless
.Cm --no-usb-check
is set.
.Pp
.Sy Notice:
Device block files are located in 
.Pa "/dev/".
The
.Pa /dev/
prefix can be omitted.
You will be prompted to select a device when not using this modifier.
Also, this option is not compatible with loop devices.
.It Fl "D", Cm --data-part
Add a supplementary data partition after installation. Requires
.Cm --icopy
or
.Cm --dd
install modifier.
.Pp
.Sy Notice:
This will only work with
.Ar imagefiles
containing MBR or GPT partition schemes.
.It Cm --data-part-fs Ar fstype
Change filesystem type for the supplementary data partition.
Default is FAT32. Requires
.Cm --icopy
or
.Cm --dd
install modifier.
.It Cm --dd-bs Ar blocksize
Specify the maximum block-size used by
.Xr dd 1
utility in
.Dq Image-Copy
mode. See
.Cm bs
option of
.Xr dd 1
utility. Default is 4M. Requires
.Cm --icopy
or
.Cm --dd
install modifier.
.Pp
.Sy Notice:
values bellow 50k can sensibly slow down the installation.
.It Fl F Ar "fstype", Cm --fs Ar fstype
Format to
.Ar fstype
instead of default FAT32 (vfat).
Supported types: vfat, exfat, ntfs, ext2, ext3, ext4, and f2fs.
Requires
.Cm --mrsync
install modifier or
.Sy format
action.
.Pp
.Sy Important Notice:
usage with
.Sy install
action is discouraged: it will be rejected in
.Dq Automatic
and
.Dq Image-Copy
modes, and could prevent UEFI boot in
.Dq Mount-Rsync
mode since the UEFI standard mandates a FAT32 partition.
.It Cm --force-hash-check
Fail and exit when no valid hash is found.
The default behavior is to prompt user when hash check
fails.
.It Cm --gpt
Enforce GPT partition scheme over default MBR. Requires
.Cm --mrsync
install modifier or
.Sy format
action.
.Pp
.Sy Important Notice:
Booting systems are generally more sensible to GPT partition types compared to MBR
partition types. It is thus advised that you explicitly set the partition type with
.Cm --part-type
modifier when enforcing GPT. This is however not required for Windows images which have
a special handling by
.Nm .
.It Fl H, Cm --no-hash-check
Skip the lookup for hash sum-files in the same folder as
.Ar "imagefile".
See
.Cm --hash-file
definition for a description of the lookup mechanism.
.It Cm --hash-file Ar hashfile
Explicitly set the
.Ar hashfile
containing the ISO hash. The default behavior is to look for files
matching those conditions:
.Bl -enum
.It
Located in the same folder as
.Ar "imagefile".
.It
Which name is the concatenation of
.Ar "imagefile",
.Dq "\&."
and the hash function name suffixed with
.Dq "sum".
.El
.Pp
Supported hash functions are md5, sha1, sha256 and sha512.
.It Fl J, Cm --no-eject
Do not eject device after unmount.
This is the default behavior with
.Sy format
action.
.It Cm --local-bootloader
Prevent download of remote bootloader and force local syslinux during installation.
This might work, but could also lower the chances of successful legacy BIOS boot, especially
when the major versions mismatch.
Requires
.Cm --mrsync
install modifier.
.It Fl M, Cm --no-mime-check
Don't assert that
.Ar imagefile
has the right mime-type.
.It Cm --no-size-check
Don't assert that selected device size is larger than
.Ar "imagefile".
.It Cm --no-usb-check
Don't assert that selected device is connected through USB bus.
.It Cm --no-wimsplit
Prevent splitting
.Pa /sources/install.wim
file in Windows ISOs. Requires
.Cm --mrsync
install modifier.
.It Cm --part-type Ar typeid
Set a specific MBR partition type, or GPT partition type when
.Cm --gpt
modifier is set. Not to be confused with filesystem modifier
.Cm "--fs".
Requires
.Cm --mrsync
install modifier or
.Sy format
action.
.Pp
List available types for GPT or MBR with the following commands:
.Pp
.D1 Sy sfdisk Cm --list-types --label No gpt
.D1 Sy sfdisk Cm --list-types --label No mbr
.It Cm --remote-bootloader Ar version
Force download of
.Xr syslinux
remote bootloader at version
.Ar "version".
Version must follow the pattern MAJOR.MINOR.
Examples: 4.10, 6.04.
That will only work with x64 system architecture.
Requires
.Cm --mrsync
install modifier.
.
.It Fl t Ar "fstype", Cm --type Ar fstype
Deprecated because of potential confusion with
.Cm "--part-type".
Use
.Fl "F", Cm --fs
instead.
.It Fl L Ar "label", Cm --label Ar label
Set partition label as
.Ar label
instead of inferring. 
.Nm
will cut labels which
are too long regarding the selected filesystem limitations.
Requires
.Cm --mrsync
install modifier or
.Sy format
action.
.It Fl y, Cm --assume-yes
Don't prompt for confirmation before erasing and partitioning USB
device.
.It Cm --
Posix end of options.
.Nm
will not process any option after this flag
and treat the upcoming item as
.Ar "imagefile".
.El
.
.Ss Install mode modifiers
These modifiers only apply to default
.Sy install
action (see
.Sx "INSTALL MODES"
bellow).
.Bl -tag
.It Cm "--icopy", Cm --dd
Assert
.Dq Image-Copy
mode and enable specific options for this mode.
.Nm
will fail if the
.Ar imagefile
is not hybrid.
.It Cm --mrsync
Assert
.Dq Mount-Rsync
mode and enable specific options for this mode.
.Nm
will fail if the
.Ar imagefile
is not an ISO 9660 filesystem.
.El
.
.
.Sh INSTALL MODES
.Pp
.Nm
has three operating modes for
.Sy install 
action. When you assert a specific mode, it allows you to provide advanced options for this mode.
.Bl -tag
.It Em Automatic
In the default 
.Dq Automatic
mode,
.Nm
will inspect
.Ar imagefile
and choose the best strategy to end up with a
bootable USB stick. These strategies are described in the below two modes.
Invoke
.Cm --inspect
action flag to print identified boot capabilities and the compatible strategy.
.It Em Image-Copy
In 
.Dq Image-Copy
mode enforceable with 
.Cm --icopy
install modifier,
.Nm
uses
.Xr dd 1
utility to make a raw copy of
.Ar "imagefile".
This is perfectly appropriate when the image file contains a builtin boot capability.
It requires to have a partition table, which can be directly copied to the target device
along with the data partitions. ISOs with this feature are called
.Dq "hybrid",
and a vast majority of GNU-Linux images are shipped that way. See 
.Xr isohybrid 1
for more information on this topic.
.It Em Mount-Rsync
In
.Dq Mount-Rsync
mode enforceable with
.Cm --mrsync
install modifier,
.Nm
creates a MBR partition table and format one partition in the USB drive and copy files
from mounted ISO. The behavior will change depending on the presence of special files to
identify whether legacy BIOS boot or UEFI boot should be preferred.
.Nm
will check conditions to figure out which ones to choose:
.Bl -enum
.It
If 
.Pa /efi/boot/*
boot files exist, choose UEFI boot and FAT32 filesystem mandated by
the standard. In which case, if a Windows
.Pa /sources/install.wim
file is found, 
.Xr wimlib-imagex 1
will be used to circumvent FAT32 filesystem size limitations.
You can prevent this behavior with 
.Cm --no-wimsplit
modifier flag.
.It
If  
.Xr syslinux 1
configuration files are found, it will install the
.Xr syslinux
bootloader to allow legacy BIOS boot and select MBR partition table.
When the local version of
.Xr syslinux
doesn't match ISO version, it will attempt to download the
closest version available in
.Lk https://www.kernel.org kernel.org
unless
.Cm --local-bootloader
flag is set.
When invoked with
.Cm --remote-bootloader Ar version
modifier,
.Nm
will ignore local version check and forces download of the
kernel.org version at
.Ar "version".
.It
If none of the above conditions are met,
.Nm
will fail and exit.
.El
.El
.
.
.Sh GUARDRAILS
.Nm
performs a set of tests with user safety and confidence in mind:
.Bl -bullet
.It
Checks
.Ar imagefile
hash sum against a hash file if one found. Supported hash algorithms
are md5, sha1, sha256 and sha512.
.It
Checks 
.Ar imagefile
mime-type with 
.Xr file 1
utility.
.It
Asserts selected device is connected through USB preventing system damages and exit
if it doesn't, with
.Xr lsblk 8
utility.
.It
Asserts that selected image is not larger than selected device.
.It
Prompts for confirmation before erasing and partitioning USB device.
.El
.
.
.Sh ENVIRONMENT
.Bl -tag
.It Ev BOOTISO_IMAGES_COMPLETIONS_PATH
This variable is interpreted by shell completion scripts as a path pointing to a directory
to look up for image and hashsum files and suggest those files when no files are matched in current working directory.
When not set, either
.Ev XDG_DOWNLOAD_DIR
if defined or
.Pa ~/Downloads
otherwise are used instead. See
.Xr xdg-user-dir 1 .
.It Ev BOOTISO_SYSLINUX_LIB_ROOT
Used in
.Dq Mount-Rsync
mode when
.Ar imagefile
has syslinux boot capability. In which case,
.Nm
will need to install a MBR boot program which it needs to locate.
This variable sets syslinux assets root, from which MBR program file will be searched.
Defaults to
.Pa /usr/lib/syslinux .
.El
.
.
.Sh EXIT STATUS
The
.Nm
utility exits 0 on success, >0 on error. Error exit status < 64 depict
unfavorable conditions external to the program such as a missing file.
On the other hand, exit status superior or equal to 64 depict an execution failure.
.
.Bl -tag
.It Sy 0
.Sy "Success".
.It Sy 1
.Sy "Assertion failed":
a safety check has not passed. See
.Sx "GUARDRAILS".
.It Sy 2
.Sy "Synopsis noncompliance":
program invocation does not match any known combination of options and operands.
.It Sy 3
.Sy "Missing boot capabilities":
.Ar imagefile
does not have boot capabilities
.Nm
knows of.
.It Sy 4
.Sy "File doesn't exists":
a file provided as option argument or operand does not exist.
.It Sy 5
.Sy "Bad file":
a file provided as option argument or operand exist, but is not of the expected format.
.It Sy 6
.Sy "Device doesn't exists":
a device provided as option argument does not exist.
.It Sy 7
.Sy "Bad device":
a device provided as option argument exists in filesystem, but is not a device node.
.It Sy 8
.Sy "No devices":
there are no drives in selection.
.It Sy 9
.Sy "Missing dependency":
.Nm
is missing a program.
.It Sy 10
.Sy "Host unreachable":
an operation involving network access could not be performed with host.
.It Sy 11
.Sy "User aborted":
the action was canceled by user.
.It Sy 12
.Sy "Missing privilege":
you need to run this command as root.
.It Sy 13
.Sy "Failed postulate":
an assumption about system state turned out false.
.It Sy 64
.Sy "I/O error":
a read/write command has unexpectedly failed.
.It Sy 65
.Sy "Program state error":
the program reached an unexpected state. This is a bug.
.It Sy 66
.Sy "Third party error":
a command has unexpectedly failed.
.El
.
.
.Sh EXAMPLES
.Bl -tag
.It Sy Probe
To have a quick feedback, probe around to check
.Nm
capabilities with given
.Dq file.iso
and list USB drives candidates:
.Pp
.D1 Nm Fl p No file.iso
.Pp
Alternatively, you can use
.Fl i
action flag to solely inspect
.Dq file.iso
or
.Fl l
action flag to solely list USB drives.
.It Sy Install
With the default
.Sy install
action in
.Dq Automatic
mode, give 
.Dq file.iso
as sole argument and you'll be prompted to select from available USB drives.
If there is only one USB device connected,
.Nm
will automatically select it:
.Pp
.D1 Nm No file.iso
.Pp
You can also explicitly set the target USB device:
.Pp
.D1 Nm Fl d No /dev/sdX file.iso
.Pp
Avoid being prompted before writing to USB drive and autoselect device when there is
exactly one connected:
.Pp
.D1 Nm Fl ay No file.iso
.Pp
Add a FAT32 data partition in
.Dq Image-Copy
mode (only works with hybrid images):
.Pp
.D1 Nm Cm --icopy Fl D No file.iso
.It Sy Format
Format the USB drive to NTFS and label it 
.Dq "SONY JOE".
Be careful with the label name, which size and character set is limited by the
target filesystem:
.Pp
.D1 Nm Fl ft No ntfs Fl L No 'SONY JOE'
.El
.Sh TROUBLESHOOTING
.Bl -bullet
.It
Some live-CD systems are not shipped with USB-3 drivers or are known to work poorly with USB-3 ports.
Always try a USB-2 port, or if you don't have one, use a USB-2 stick, before considering
the boot a failure. As of 2020, Windows 10 (UEFI) is among those systems.
.It
If legacy BIOS boot doesn't work, be advised that
UEFI-compliant boot systems have a Compatibility Support Module (CSM) option to enable legacy BIOS boot.
.It
If
.Nm
does not detect your USB device, you can try running
.Pp
.D1 Sy udevadm settle
.Pp
and try again.
.It
If the
.Ar imagefile
has UEFI support and the boot fails on a UEFI-compatible machine, one can try different partition types with
.Cm --part-type
modifier, because some systems will assume specific types and refuse to load data otherwise.
This is especially prevalent with GPT partition tables.
.El
.
.
.Sh COPYRIGHT
Copyright Jules Sam. Randolph.
.Pp
GPLv3 License:
.Lk https://www.gnu.org/licenses/gpl-3.0
This is free software: you are free to change and redistribute it.  There is NO WARRANTY, to the extent permitted by law.
.Sh SEE ALSO
.\" Should be sorted by section and alphabetically
.Xr dd 1 ,
.Xr isohybrid 1 ,
.Xr syslinux 1 ,
.Xr wimlib-imagex 1
.
.
.Sh COMPATIBILITY
.Nm
should work with any terminal emulator and the Linux console. More specifically, the output device should
support the following features:
.Bl -bullet
.It
ASCII character set;
.It
ECMA-48 SGR sequences to feature color, bold and underline
text attributes as documented in
.Xr console_codes "4".
.El
.
.
.Sh STANDARDS
.Nm
is compliant with:
.Bl -bullet
.It
.St "-p1003.1-2008",
Ch. 12,
.Dq "Utility Conventions";
.It
Filesystem Hierarchy Standard, version 3.0.
.El
.
.
.\" .Sh HISTORY
.Sh AUTHORS
.An "Jules Sam. Randolph" Aq "jules.sam.randolph@gmail.com"
.
.
.\" .Sh BUGS